//
// Created by martin on 3/22/22.
//

#include "FtpServer.h"
#include "Configurer.h"
#include "muduo/base/Logging.h"
#include "muduo/base/AsyncLogging.h"
#include "muduo/net/EventLoop.h"

#include <unistd.h>

using namespace ftp;

// roll size for asyncLogging
static const off_t kRollSize = 1 * 1024 * 1024;

//--------------------------------------------------------------
// local function list

static void initLogger();
static void initConfig();
static std::string initFtpRootPath();

//--------------------------------------------------------------
// local function definitions

void initConfig()
{
	//Configurer::instance().load(std::string("config.ini"));
	Configurer::instance().load(kDefaultConfigFilePath);
}

muduo::AsyncLogging* g_asyncLog = NULL;
inline muduo::AsyncLogging* getAsyncLog()
{
	return g_asyncLog;
}

void asyncLog(const char* msg, int len)
{
	muduo::AsyncLogging* logging = getAsyncLog();
	if (logging)
	{
		logging->append(msg, len);
	}
}

void initLogger()
{
	muduo::Logger::setLogLevel(muduo::Logger::INFO);
	std::string asyncLogBaseName = Configurer::instance().getItemString(
		"LogBaseName", "eftp");
	if (Configurer::instance().getItemInt("EnableAsyncLogging") == 1) {
		static muduo::AsyncLogging log(asyncLogBaseName.c_str(), kRollSize);
		g_asyncLog = &log;
		muduo::Logger::setOutput(asyncLog);
		log.start();
	}
}

// Warning: logged in user for Unix/Linux must own read/write permission on the ftp root directory.
std::string initFtpRootPath()
{
	//Configurer::instance().checkRootPath();
	return "/home/martin/ftproot";
}

//--------------------------------------------------------------
// application entry

int main(int argc, char* argv[])
{
	LOG_INFO << "pid = " << getpid();
	initConfig();
	initLogger();
	const std::string localRootPath = initFtpRootPath();

	int port = Configurer::instance().getItemInt("ListenPort");
	int numberOfThread = Configurer::instance().getItemInt("NumberOfThread");

	muduo::net::EventLoop loop;
	muduo::net::InetAddress listenAddr(static_cast<uint16_t>(port));
	FtpServer server(&loop, listenAddr);
	server.addAnonymousUser(localRootPath, Permission::ReadOnly);
	server.addUser("admin", "123456", localRootPath, Permission::All);
	server.addUser("uploader", "123456", localRootPath, Permission::All);
	server.setThreadNum(numberOfThread);
	server.start();
	loop.loop();
	return 0;
}
